package com.eastedu.template.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * The type Continuous elements.
 */
public class ContinuousElements {
    /**
     * The entry point of application.
     *
     * @param args the input arguments
     */
    public static void main(String[] args) {
        List<List<String>> list = new ArrayList<>();
        list.add(Arrays.asList("A", "B", "B", "C", "C1", "C", "C", "D", "D", "D"));
        list.add(Arrays.asList("A","X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9"));

        List<MergeInfo> result = findContinuousElements(list);

        for (MergeInfo mergeInfo : result) {
            System.out.println("起始坐标：(" + mergeInfo.getStart().getX() + ", " + mergeInfo.getStart().getY() + "), 终止坐标：(" + mergeInfo.getEnd().getX() + ", " + mergeInfo.getEnd().getY() + ")");
        }
    }

    /**
     * Find continuous elements list.
     *
     * @param list the list
     * @return the list
     */
    public static List<MergeInfo> findContinuousElements(List<List<String>> list) {
        List<MergeInfo> mergeInfos = new ArrayList<>();

        int rows = list.size();
        int cols = list.get(0).size();

        // 横向查找
        for (int row = 0; row < rows; row++) {
            int startCol = 0;
            while (startCol < cols) {
                String current = list.get(row).get(startCol);
                int endCol = startCol + 1;
                while (endCol < cols && list.get(row).get(endCol).equals(current)) {
                    endCol++;
                }
                if (endCol - startCol > 1) {
                    mergeInfos.add(new MergeInfo(new Point(row, startCol), new Point(row, endCol - 1)));
                }
                startCol = endCol;
            }
        }

        // 纵向查找
        for (int col = 0; col < cols; col++) {
            int startRow = 0;
            while (startRow < rows) {
                String current = list.get(startRow).get(col);
                int endRow = startRow + 1;
                while (endRow < rows && list.get(endRow).get(col).equals(current)) {
                    endRow++;
                }
                if (endRow - startRow > 1) {
                    mergeInfos.add(new MergeInfo(new Point(startRow, col), new Point(endRow - 1, col)));
                }
                startRow = endRow;
            }
        }

        return mergeInfos;
    }

    static class MergeInfo {
        private Point start;
        private Point end;

        /**
         * Instantiates a new Merge info.
         *
         * @param start the start
         * @param end   the end
         */
        public MergeInfo(Point start, Point end) {
            this.start = start;
            this.end = end;
        }

        /**
         * Gets start.
         *
         * @return the start
         */
        public Point getStart() {
            return start;
        }

        /**
         * Gets end.
         *
         * @return the end
         */
        public Point getEnd() {
            return end;
        }
    }

    /**
     * The type Point.
     */
    static class Point {
        private int x;
        private int y;

        /**
         * Instantiates a new Point.
         *
         * @param x the x
         * @param y the y
         */
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        /**
         * Gets x.
         *
         * @return the x
         */
        public int getX() {
            return x;
        }

        /**
         * Gets y.
         *
         * @return the y
         */
        public int getY() {
            return y;
        }
    }
}